/**
 * -----------------------------------------------------------------
 * 介绍类和对象的概念 (类有属性和方法，可以通过new关键字创建很多对象)
 * 类就是拥有相等功能和相同的属性的对象的集合 -- 抽象的
 * 对象就是类的实例 -- 具体
 * 
 * 生活角度看类和对象
 * 如果人是类，小名就是对象、小花也是对象
 * 如果电脑是类，我桌上的这两台电脑就是对象
 */

class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
  say() {
    alert(`${this.name} is eating`)
  }
}

// 调用
// var wang = new Person("wang", 20);
// wang.say();
// var zhang = new Person("zhang", 50);
// zhang.say();

/**
 * -----------------------------------------------------------------
 * 继承（子类继承父类）
 * 继承可将公共方法抽离出来，提高复用，减少冗余
 */

class Student extends Person {
  constructor(name, age, number) {
    super(name, age);
    this.number = number;
  }
  study() {
    alert(`${this.name} is studing`);
  }
}

// var xiaoming = new Student('xiaoming', 10, 'A1');
// xiaoming.say();
// xiaoming.study();

/**
 * -----------------------------------------------------------------
 * 封装
 * 1. public 完全开放
 * 2. protected 对子类开放
 * 3. private 对自己开放
 * 目前ts内可用，比较规范
 * 以下代码需ts环境下运行 http://www.typescriptlang.org/play/
 * 
 * 作用：
 * 1. 减少耦合，不该外露的不外露
 * 2. 利于数据，接口的权限管理
 * 3. ES6暂时不支持，一般认为 _开头的属性是private
 */

// class Person {
//   name: any
//   age: number
//   protected weight: any // 受保护的属性，只有自己或者子类可以访问
//   constructor(name: any, age: number) {
//     this.name = name;
//     this.age = age;
//     this.weight = 120
//   }
//   say() {
//     alert(`${this.name} is eating`)
//   }
// }

// class Student extends Person {
//   number: number
//   private girlfriend: any
//   constructor(name: any, age: number, number: number) {
//     super(name, age);
//     this.number = number;
//     this.girlfriend = 'xiaoli'
//   }
//   study() {
//     alert(`${this.name} is studing`);
//   }
//   getWeight() {
//     alert(`weight ${this.weight}`)
//   }
// }

// let xiaoming = new Student('xiaoming', 10, 12)
// xiaoming.getWeight()


/**
 * -----------------------------------------------------------------
 * 多态
 * 1. 同一个接口，不同的实现
 * 2. JS 应用极少
 * 3. 需要结合Java等语言的接口，重写，重载等功能
 * 
 * 作用：
 * 保持了子类的开放性和灵活性
 * 面向接口编程
 * (JS引用较少)
 */

class A extends Person {
  constructor(name) {
    super(name)
  }
  saySomething() {
    alert("Im A")
  }
}

class B extends Person {
  constructor(name) {
    super(name)
  }
  saySomething() {
    alert("Im B")
  }
}

// let a = new A('A')
// a.saySomething()
// let b = new B('B')
// b.saySomething()



/**
 * -----------------------------------------------------------------
 * JS应用实例
 * JQuery
 */

class JQuery {
  constructor(selector) {
    let slice = Array.prototype.slice
    let dom = slice.call(document.querySelectorAll(selector))
    let len = dom ? dom.length : 0
    for (let i = 0; i < len; i++) {
      this[i] = dom[i]
    }
    this.length = len
    this.selector = selector
  }
  append(node) {
    // ...
  }
  addClass(name) {
    // ...
  }
}

window.$ = function(selector) {
  // 工厂模式
  return new JQuery(selector)
}


/**
 * -----------------------------------------------------------------
 * 为什么要使用面向对象
 * 程序执行：顺序，判断，循环  ---结构化
 * 面向对象 --- 数据结构化
 * 
 * 对于计算机，结构化的东西才是最简单的
 * 编程应该 简单 & 抽象
 * 
 * 总结
 * 初始类，类的概念
 * 三要素：封装，继承，多态
 * jq的应用示例
 * 意义：数据结构化
 */